package com.ffad.frame.db.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;

import com.ffad.frame.db.core.DataSourceContextHolder;

/**
 * 在service层觉得数据源 
 *  
 * 必须在事务AOP之前执行，所以实现Ordered,order的值越小，越先执行 
 * 如果一旦开始切换到写库，则之后的读都会走写库
 * 
 * @author songxudong[song_xd@suixingpay.com]
 * 
 */
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Component
public class DataSourceServiceAopConfig implements PriorityOrdered {
	private static Logger LOGGER = LoggerFactory.getLogger(DataSourceServiceAopConfig.class);

	// execution(* *com.wator.grad.*.*.service..*.*(..)) and 
	@Before("@annotation(com.wator.grad.frame.common.db.annotation.ReadDataSource)")
	public void setReadDataSourceType() {
		LOGGER.info("调用读操作方法");
		DataSourceContextHolder.setRead();
	}

	@Before("execution(* *com.wator.grad.*.*.service..*.*(..)) "
			+ " and @annotation(com.wator.grad.frame.common.db.annotation.WriteDataSource) ")
	public void setWriteDataSourceType() {
		LOGGER.info("调用写操作方法");
		DataSourceContextHolder.setWrite();
	}
	
	@Pointcut("@annotation(com.wator.grad.frame.common.db.annotation.ReadDataSource)")
	private void addTask() {}
	
	@Around("addTask()")
    public Object aroundInterviewTask(ProceedingJoinPoint pjp) throws Throwable{
		LOGGER.info("调用读操作方法");
		DataSourceContextHolder.setRead();
		
        Object[] args = pjp.getArgs();
        Object retVal = pjp.proceed(args);
        
        return retVal;
    }
	

	@Override
	public int getOrder() {
		/**
		 * 值越小，越优先执行 要优于事务的执行 在启动类中加上了@EnableTransactionManagement(order = 10)
		 */
		return 1;
	}

}
